package controllers;

import java.util.Collection;
import java.util.Date;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import domain.Event;
import domain.Participant;
import domain.Registration;
import services.EventService;
import services.ParticipantService;
import services.RegistrationService;

@Controller
@RequestMapping("/registration/participant")
public class ParticipantRegistrationController extends AbstractController {

	// Constructors -----------------------------------------------------------

	public ParticipantRegistrationController() {
		super();
	}

	// Services ---------------------------------------------------------------

	@Autowired
	private ParticipantService ParticipantService;

	@Autowired
	private RegistrationService registrationService;

	@Autowired
	private EventService eventService;

	// List registration
	// ------------------------------------------------------------

	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView list() {
		ModelAndView result;
		Collection<Registration> registrations;
		registrations = registrationService.findByPrincipal();
		result = new ModelAndView("registration/list");
		result.addObject("requestURI", "registration/participant/list.do");
		result.addObject("registrations", registrations);

		return result;
	}

	@RequestMapping(value = "/create", method = RequestMethod.GET)
	public ModelAndView editParticipant(@RequestParam int eventId) {
		ModelAndView result;

		Participant p = ParticipantService.findByPrincipal();
		Event e = eventService.findOne(eventId);

		// Assert.isTrue(p!=null);
		// Assert.isTrue(e!=null);

		Registration r = registrationService.create(p, e);

		result = createEditModelAndView(r);

		return result;
	}

	protected ModelAndView createEditModelAndView(Registration r) {
		ModelAndView result;

		result = createEditModelAndView(r, null);

		return result;
	}

	protected ModelAndView createEditModelAndView(Registration r, String message) {
		ModelAndView result;
		;
		result = new ModelAndView("registration/create");
		result.addObject("registration", r);
		if (r.getId() == 0) {
			result.addObject("create", true);
		} else {
			result.addObject("create", false);
		}

		if (r.getEvent().getFinishMoment()
				.before(new Date(System.currentTimeMillis() - 1))) {
			result.addObject("expired", true);
		}
		result.addObject("message", message);

		if (r.getEvent().getStartMoment()
				.after(new Date(System.currentTimeMillis() - 1))) {
			result.addObject("delete", true);
		}
		result.addObject("message", message);

		return result;
	}

	// Edit ---------------------------------------------------------------

	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	public ModelAndView editChallenge(@RequestParam int registrationId) {
		ModelAndView result;
		Registration r = registrationService.findOne(registrationId);

		result = createEditModelAndView(r);
		return result;
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST, params = "save")
	public ModelAndView saveParticipant(@Valid Registration r,
			BindingResult binding) {
		ModelAndView result;

		if (binding.hasErrors()) {
			result = createEditModelAndView(r);

		} else {
			try {

				registrationService.save(r);
				result = new ModelAndView("redirect:list.do");

			} catch (Throwable oops) {
				result = createEditModelAndView(r, "registration.commit.error");

			}

		}

		return result;
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST, params = "delete")
	public ModelAndView delete(Registration r, BindingResult binding) {
		ModelAndView result;

		try {
			registrationService.delete(r);
			result = new ModelAndView("redirect:list.do");
		} catch (Throwable oops) {
			result = createEditModelAndView(r, "registration.commit.error");
		}

		return result;
	}

}
